﻿// //  ********************************************************************************
// //  Copyright (C) 2016 Sebastian Kenter. All rights reserved.
// // 
// //  Name    : MultiServerEngine | ServerFramework | ServerApplication.cs
// //  Created : 2016 - 02 - 16 20:53
// //  Modified: 2016 - 02 - 20 12:32
// //  ********************************************************************************

using System.IO;
using Autofac;
using Autofac.Configuration;
using ExitGames.Logging;
using ExitGames.Logging.Log4Net;
using log4net;
using log4net.Config;
using Photon.SocketServer;
using Photon.SocketServer.ServerToServer;
using ServerFramework.Implementation.Configuration;
using ServerFramework.Interfaces.Application;
using ServerFramework.Interfaces.Client;
using ServerFramework.Interfaces.Server;
using LogManager = ExitGames.Logging.LogManager;

namespace ServerFramework.Implementation.Application
{
    public class ServerApplication : ApplicationBase
    {
        private ILogger Logger { get; set; }
        private IServerApplication Server { get; set; }
        private IServerPeerFactory ServerPeerFactory { get; set; }
        private IClientPeerFactory ClientPeerFactory { get; set; }

        protected override PeerBase CreatePeer(InitRequest initRequest)
        {
            PeerConfig peerConfig = new PeerConfig();
            peerConfig.AddPeerConfig(initRequest);
            return ClientPeerFactory.CreatePeer<PeerBase>(peerConfig);
        }

        protected override ServerPeerBase CreateServerPeer(InitResponse initResponse, object state)
        {
            PeerConfig peerConfig = new PeerConfig();
            peerConfig.AddPeerConfig(initResponse);
            return ServerPeerFactory.CreatePeer<ServerPeerBase>(peerConfig);
        }

        protected override void Setup()
        {
            InitializeLogger();
            InitializeAutofac();

            Server.Setup();
        }

        protected override void TearDown()
        {
            Server.TearDown();
        }

        protected override void OnStopRequested()
        {
            Server.OnStopRequested();
            base.OnStopRequested();
        }

        protected override void OnServerConnectionFailed(int errorCode, string errorMessage, object state)
        {
            Server.OnServerConnectionFailed(errorCode, errorMessage, state);
        }

        private void InitializeLogger()
        {
            LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance);
            GlobalContext.Properties["AppPath"] = BinaryPath;
            GlobalContext.Properties["LogName"] = ApplicationName;
            XmlConfigurator.ConfigureAndWatch(new FileInfo(Path.Combine(BinaryPath, "log4net.config")));
            Logger = LogManager.GetLogger(ApplicationName);
        }

        private void InitializeAutofac()
        {
            ContainerBuilder containerBuilder = new ContainerBuilder();

            containerBuilder.RegisterInstance(this).SingleInstance();
            containerBuilder.RegisterInstance(Logger).As<ILogger>();
            containerBuilder.RegisterType<IServerPeerFactory>();
            containerBuilder.RegisterType<IClientPeerFactory>();
            containerBuilder.RegisterType<IServerApplication>();
            containerBuilder.RegisterModule(
                new XmlFileReader(Path.Combine(BinaryPath, string.Concat("Modules\\", ApplicationName, ".config"))));

            IContainer container = containerBuilder.Build();

            using (ILifetimeScope scope = container.BeginLifetimeScope())
            {
                Logger = scope.Resolve<ILogger>();
                ServerPeerFactory = scope.Resolve<IServerPeerFactory>();
                ClientPeerFactory = scope.Resolve<IClientPeerFactory>();
                Server = scope.Resolve<IServerApplication>();
            }
        }
    }
}
